using AnimCollections;
using DA.AnimGraph;
using System.Collections.Generic;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;
using Object = UnityEngine.Object;

[ExecuteInEditMode]
[RequireComponent(typeof(Animator))]
public class AGEPreviewPlayer : MonoBehaviour {

    public bool isPlaying;
    public bool isHolding;

    private AnimGraphController controller;
    private DynamicBlackboard dynamicBlackboard;
    // private Dictionary<string, AGABlackboardType> blackboardInfo;

    public void Holding() {
        isHolding = true;
        var animator = GetComponent<Animator>();
        controller = new AnimGraphController(animator, gameObject.name);
    }

    public void Play() {
        if (isHolding && !isPlaying) {
            controller.Play();
            isPlaying = true;
        }
    }

    public unsafe AnimGraphController* GetAnimGraphController() {
        return (AnimGraphController*)UnsafeUtility.AddressOf(ref controller);
    }

    public unsafe void StartPreview2(AnimGraphPublishAsset agpAsset,
        Dictionary<AUID, Object> resources,
        DynamicBlackboard dbb,
        Blackboard bb,
        string slotName, string fileName) {

        dynamicBlackboard = dbb;

        AnimGraph*[] graphs = AGPParser.ParseGraph(agpAsset);
        var graph = graphs[0];
        // todo:临时，覆盖显示名称
        graph->name = fileName;
        graph->SetBlackboard(bb);

        var buildContext = new BuildContext() { resourcesMap = resources };
        if (slotName == "root") {
            // Debug.Assert(controller.graphCount == 0, "暂不支持重复添加 root graph");
            controller.SetupRootGraph(graph, buildContext);
            Play();
        } else if (slotName == null && controller.graphCount == 0) {
            controller.SetupRootGraph(graph, buildContext);
            Play();
        } else if (slotName == null) {
            controller.AddGraphAndBuildPlayable(graph, buildContext);
        } else {
            controller.AddGraphAndConnectToSlot(graph, slotName, buildContext);
        }
    }

    public unsafe void StartPreview(
        AnimGraphPublishAsset agpAsset,
        Dictionary<AUID, Object> resources,
        DynamicBlackboard dbb,
        Blackboard bb,
        Dictionary<string, AGABlackboardType> bbInfo) {

        var animator = GetComponent<Animator>();
        dynamicBlackboard = dbb;
        // blackboardInfo = bbInfo;

        AnimGraph*[] graphs = AGPParser.ParseGraph(agpAsset);
        var graph = graphs[0];
        graph->SetBlackboard(bb);

        var buildContext = new BuildContext() { resourcesMap = resources };

        controller = new AnimGraphController(animator, gameObject.name);
        controller.SetupRootGraph(graph, buildContext);
        controller.Play();
        isPlaying = true;
        isHolding = true;
    }

    public void StopPreview() {
        isPlaying = false;
        isHolding = false;
        controller.Dispose();
        if (dynamicBlackboard.isValid) {
            dynamicBlackboard.Dispose();
        }
        // blackboardInfo = null;
    }

    private void Update() {
        if (isHolding && isPlaying) {
            var dt = Time.deltaTime;
            controller.UpdateBlackboardAddress(dynamicBlackboard.baseAddr);
            controller.Evaluate(dt, out AnimOutputData outputData);
        }
    }

    private void OnDisable() {
        StopPreview();
    }

}
